//
//  LXLocationAction.m
//  LXLocationRelated
//
//  Created by Livespro on 2017/10/19.
//  Copyright © 2017年 Livesxu. All rights reserved.
//

#import "LXLocationAction.h"

#import <UIKit/UIKit.h>

#import "LXLocationAction+AnalyseHelper.h"

#import "LXHandleDatas.h"

#import "CLLocation+Sino.h"

#define kLocationAwakenNoti @"LocationAwakenNotification"
#define kMotionStart @"MotionStartNotification"
#define kMotionStop  @"MotionStopNotification"

@interface LXLocationAction ()<CLLocationManagerDelegate>
{
    UIBackgroundTaskIdentifier _backgroundTaskIdentifier;
}

@property (nonatomic, assign) BOOL isStart;

@end

@implementation LXLocationAction

- (void)dealloc{
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:kLocationAwakenNoti object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
    
    [self removeObserver:self forKeyPath:@"self.isRun"];
}

+ (instancetype)shareLocation{
    
    static LXLocationAction *location = nil;
    
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        location = [[LXLocationAction alloc]init];
        
    });
    return location;
}

- (instancetype)init{
    self = [super init];
    if (self) {
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(awakenAction) name:kLocationAwakenNoti object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil];
        
        [self addObserver:self forKeyPath:@"self.isRun" options:NSKeyValueObservingOptionNew context:nil];//传感器启动与否绑定isRun
        
        _backgroundTaskIdentifier = UIBackgroundTaskInvalid;
    }
    return self;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    
    if ([keyPath isEqualToString:@"self.isRun"]) {
        
        NSNumber *newIsRun = change[@"new"];
        
        if (newIsRun.boolValue) {
            
            [[NSNotificationCenter defaultCenter] postNotificationName:kMotionStart object:nil];
        } else {
            
            [[NSNotificationCenter defaultCenter] postNotificationName:kMotionStop object:nil];
        }
    }
    
}

#pragma mark - 申请后台Task
- (void)beginBackgroundTask {
    if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground) {
        return;
    }
    if (_backgroundTaskIdentifier != UIBackgroundTaskInvalid) {
        return;
    }
    //标记后台执行
    [[NSUserDefaults standardUserDefaults] setObject:@(YES) forKey:@"APPBackGroundRun"];
    
    __weak __typeof(self) weakSelf = self;
    _backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        
        [weakSelf endBackgroundTask];
    }];
}

- (void)endBackgroundTask {
    if (_backgroundTaskIdentifier != UIBackgroundTaskInvalid) {
        [[UIApplication sharedApplication] endBackgroundTask:_backgroundTaskIdentifier];
        _backgroundTaskIdentifier = UIBackgroundTaskInvalid;
    }
}

#pragma mark - 进入前台
- (void)applicationDidBecomeActive:(NSNotification *)notification{
    //同步历史
    
    //标记前台执行
    [[NSUserDefaults standardUserDefaults] setObject:@(NO) forKey:@"APPBackGroundRun"];
    //进入前台结束后台
    [self endBackgroundTask];
    
    [[LXHandleDatas shareHandle] handleMonitorIn:[NSString stringWithFormat:@"app进入前台 - %@%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd)] Time:[NSDate date] User:@"01"];
}

#pragma mark - 进入后台
- (void)applicationDidEnterBackground:(NSNotification *)notification{
    
    [self awakenAction];
    
    [[LXHandleDatas shareHandle] handleMonitorIn:[NSString stringWithFormat:@"app进入后台 - %@%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd)] Time:[NSDate date] User:@"01"];
}

#pragma mark - 通知唤醒操作
- (void)awakenAction{
    //开启后台
    [self beginBackgroundTask];
    
    [self startUpdating];
}

- (CLLocationManager *)locationM{
    
    if (!_locationM) {
        
        _locationM = [[CLLocationManager alloc] init];
        _locationM.delegate = self;
        
        // 设置每隔多远定位一次(1次  111km/100m)
        // 最新的位置距离上一次位置之间的距离大于10m, 才会通过代理告诉外界
        _locationM.distanceFilter = kLocationDistanceFilter;
        
        //生成新的标题事件所需的最小角度变化(以度为单位) - 暂时关闭
//        _locationM.headingFilter = 30;
        
        // 定位精确度
        // 定位精确度越高, 越耗电, 而且, 定位时间越长
        _locationM.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
        
        _locationM.pausesLocationUpdatesAutomatically = NO;
        
        _locationM.activityType = CLActivityTypeAutomotiveNavigation;
        
        if([_locationM respondsToSelector:@selector(requestAlwaysAuthorization)]){
            [_locationM requestAlwaysAuthorization];
        }
        if ([_locationM respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
            [_locationM requestWhenInUseAuthorization];
        }
        if ([_locationM respondsToSelector:@selector(allowsBackgroundLocationUpdates)]) {
            _locationM.allowsBackgroundLocationUpdates = YES;
        }
        
    }
    return _locationM;
}

- (void)startUpdating {
    
    if (self.isStart) {
        
        return;
    }
    
    self.isStart = YES;
    
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
        [self locationM];
    } else {
        [self.locationM setDelegate:self];
        
        [self.locationM startUpdatingLocation];
//        if ([CLLocationManager headingAvailable]) {
//            [self.locationM startUpdatingHeading];
//        }
    }
}

- (void)stopUpdating {
    
    if (!self.isStart) {
        
        return;
    }
    self.isStart = NO;
    
    [_locationM setDelegate:nil];
    
    [_locationM stopUpdatingLocation];
    
//    if ([CLLocationManager headingAvailable]) {
//        [_locationM stopUpdatingHeading];
//    }
    _locationM = nil;
}

#pragma mark - CLLocationManagerDelegate
// 1.告诉代理可以使用新的位置数据
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations;{
    
    [self analyseLocation:[manager.location earthToMars] Heading:manager.heading];
    
    if (self.locationBlock) {
        
        self.locationBlock(manager.location);
    }
}

// 2.告诉代理位置管理者无法检索位置的值
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error;{
    
}

// 3.告诉代理,更新将不再被推迟
- (void)locationManager:(CLLocationManager *)manager didFinishDeferredUpdatesWithError:(NSError *)error;{
    
}

// 4.告诉代理可以使用新的位置的值
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation;{
    
}

// 5.告诉代理,位置更新已暂停
- (void)locationManagerDidPauseLocationUpdates:(CLLocationManager *)manager;{
    
}

// 6.告诉代理,已经恢复位置更新的交付
- (void)locationManagerDidResumeLocationUpdates:(CLLocationManager *)manager;{
    
}

// 7.告诉代理位置管理者接收到更新的标题信息
- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading;{
    
    
}

//8.程序更改了授权状态
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    //针对未鉴权情况
    if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) {
        //8.0及其以上，请求权限方式
        if ([manager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
            [manager requestAlwaysAuthorization];
        } else {//8.0以下，直接由定位触发鉴权
            [manager startUpdatingLocation];
        }
        return;
    }
    
    //拥有访问权限
    if (status == kCLAuthorizationStatusAuthorized
        || status == kCLAuthorizationStatusAuthorizedWhenInUse
        || status == kCLAuthorizationStatusAuthorizedAlways) {
        if (self.isStart == YES) {
            //如果需要启用位置
            [manager startUpdatingLocation];
            
//            if ([CLLocationManager headingAvailable]) {
//                [manager startUpdatingHeading];
//            }
        }
        return;
    }
    
    //位置服务不可用(待定)
//    if ([self isDelegateValidForSelector:@selector(locationCollectionLocationServiceDidBecomeDenied:)]) {
//        [self.delegate locationCollectionLocationServiceDidBecomeDenied:self];
//    }
}


@end
